package com.superhelper.common.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.superhelper.common.domain.TakeOutShopInfo;
import com.superhelper.common.domain.baidu.BdPushEntity;
import com.superhelper.common.utils.CryptUtil;
import com.superhelper.common.utils.HttpClientHelper;
import com.superhelper.common.utils.JsonHelper;

public class BaiduService {
    private final Logger log = LoggerFactory.getLogger(BaiduService.class);
    private String url = "https://api.waimai.baidu.com/";
    private HttpClientHelper httpHelper = new HttpClientHelper();
    private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 200, 1L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>());

    @SuppressWarnings("serial")
    private Map<String, String> sourceMap = new HashMap<String, String>() {
        {
            put("64773", "2302f9b19b8a3092"); // 测试项目
            put("64493", "095ca5e1a55f3042"); // 测试项目
            put("64492", "4b0b69b7a10938b1"); // 测试项目
            put("64341", "23798e8f1e529c7c"); // 测试KA项目
            put("31198", "6fb82f16e94c2f74"); // 正式
            put("31384", "79a9b363a658c8e3"); // 正式
            put("32142", "036b63b0cb23bc23"); // 正式KA

        }
    };

    public String getSourceSecret(String source) {
        return this.sourceMap.get(source);
    }

    /**
     * 获取公共参数
     */
    public BdPushEntity getBdPushEntity(String source, String cmd, Map<String, Object> body) {
        BdPushEntity entity = new BdPushEntity();
        String secret = sourceMap.get(source);
        entity.setCmd(cmd);
        entity.setSource(source);
        entity.setSecret(secret);
        entity.setEncrypt("");
        entity.setVersion("3");
        entity.setTimestamp(System.currentTimeMillis() / 1000);
        entity.setTicket(UUID.randomUUID().toString().toUpperCase());
        if (body != null && !body.isEmpty()) {
            entity.setBody(body);
        }
        return entity;
    }

    /**
     * 请求参数
     */
    public Map<String, String> converParams(BdPushEntity entity) {
        Map<String, String> sysParams = new TreeMap<String, String>();
        sysParams.put("cmd", entity.getCmd());
        sysParams.put("timestamp", entity.getTimestamp() + "");
        sysParams.put("ticket", entity.getTicket());
        sysParams.put("version", entity.getVersion());
        sysParams.put("source", entity.getSource());
        sysParams.put("secret", entity.getSecret());
        sysParams.put("encrypt", entity.getEncrypt());
        sysParams.put("body", "");
        if (entity.getBody() != null) {
            sysParams.put("body", JsonHelper.toJson(entity.getBody()));
        }
        String queryString = "";
        Set<String> set = new TreeSet<String>(sysParams.keySet());
        for (String key : set) { // 遍历所有key
            String value = sysParams.get(key);
            queryString += key + "=" + value + "&";
        }
        queryString = queryString.substring(0, queryString.length() - 1);
        String sign = CryptUtil.md5(queryString).toUpperCase();
        entity.setSign(sign);
        sysParams.put("sign", sign);
        return sysParams;
    }

    /**
     * 创建商户
     * 
     * @return
     */
    public boolean createShop(String source, String name) {

        Map<String, Object> body = new HashMap<String, Object>();
        body.put("supplier_id", "1429542949");
        body.put("shop_id", System.currentTimeMillis());
        body.put("name", name);
        body.put("address", "广州市海珠区");
        body.put("phone", "13800138000");
        body.put("service_phone", "13800138000");
        body.put("province", "7");
        body.put("city", "257");
        body.put("county", "2338");
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        Map<String, String> c = new HashMap<String, String>();
        c.put("category1", "1");
        c.put("category2", "2");
        c.put("category3", "3");
        list.add(c);
        body.put("categorys", list);
        body.put("longitude", "113.320773");
        body.put("latitude", "23.09177");
        List<Map<String, Object>> delivery_region = new ArrayList<Map<String, Object>>();

        Map<String, Object> region = new HashMap<String, Object>();
        region.put("name", "海珠区");
        region.put("delivery_time", "60");
        region.put("delivery_fee", "400");
        region.put("min_order_price", "1");
        List<Object> regions = new ArrayList<Object>();
        List<Map<String, String>> regionAre = new ArrayList<Map<String, String>>();
        regions.add(regionAre);
        region.put("region", regions);
        Map<String, String> are = new HashMap<String, String>();
        are.put("longitude", "113.320773");
        are.put("latitude", "23.09177");
        regionAre.add(are);
        Map<String, String> are1 = new HashMap<String, String>();
        are1.put("longitude", "113.420773");
        are1.put("latitude", "23.19177");
        regionAre.add(are1);
        Map<String, String> are2 = new HashMap<String, String>();
        are2.put("longitude", "113.520773");
        are2.put("latitude", "23.29177");
        regionAre.add(are2);
        Map<String, String> are3 = new HashMap<String, String>();
        are3.put("longitude", "113.620773");
        are3.put("latitude", "23.39177");
        regionAre.add(are3);
        delivery_region.add(region);

        body.put("delivery_region", delivery_region);
        body.put("coord_type", "bdll");
        List<Object> times = new ArrayList<Object>();
        Map<String, String> time1 = new HashMap<String, String>();
        time1.put("start", "08:00");
        time1.put("end", "14:00");
        times.add(time1);
        body.put("business_time", times);
        body.put("book_ahead_time", "");
        body.put("invoice_support", "2");
        body.put("package_box_price", "1.00");
        body.put("business_form_id", "");
        body.put("shop_code", "2022");
        BdPushEntity entity = getBdPushEntity(source, "shop.create", body);
        try {
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("querySupplier->:{}", result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 创建商户
     * 
     * @return
     */
    public boolean updateShop(String source, String shopId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("baidu_shop_id", shopId);
        body.put("name", "KA测试店铺");
        body.put("address", "广州市海珠区赤岗路");
        body.put("phone", "13800138000");
        body.put("service_phone", "13533138776");
        body.put("province", "7");
        body.put("city", "257");
        body.put("county", "2338");
        body.put("longitude", "113.320773");
        body.put("latitude", "23.09177");
        List<Map<String, Object>> delivery_region = new ArrayList<Map<String, Object>>();

        Map<String, Object> region = new HashMap<String, Object>();
        region.put("name", "海珠区");
        region.put("delivery_time", "60");
        region.put("delivery_fee", "100");
        region.put("min_order_price", "1");
        region.put("min_buy_free", "100");
        List<Object> regions = new ArrayList<Object>();
        List<Map<String, String>> regionAre = new ArrayList<Map<String, String>>();
        regions.add(regionAre);
        region.put("region", regions);
        Map<String, String> are = new HashMap<String, String>();
        are.put("longitude", "113.320773");
        are.put("latitude", "23.09177");
        regionAre.add(are);
        Map<String, String> are1 = new HashMap<String, String>();
        are1.put("longitude", "114.420773");
        are1.put("latitude", "23.29177");
        regionAre.add(are1);
        Map<String, String> are2 = new HashMap<String, String>();
        are2.put("longitude", "114.520773");
        are2.put("latitude", "23.49177");
        regionAre.add(are2);
        Map<String, String> are3 = new HashMap<String, String>();
        are3.put("longitude", "114.620773");
        are3.put("latitude", "23.59177");
        regionAre.add(are3);
        Map<String, String> are33 = new HashMap<String, String>();
        are33.put("longitude", "112.620773");
        are33.put("latitude", "22.59177");
        regionAre.add(are33);
        Map<String, String> are4 = new HashMap<String, String>();
        are4.put("longitude", "113.320773");
        are4.put("latitude", "23.09177");
        regionAre.add(are4);
        delivery_region.add(region);
        body.put("delivery_region", delivery_region);
        body.put("coord_type", "bdll");
        List<Object> times = new ArrayList<Object>();
        Map<String, String> time1 = new HashMap<String, String>();
        time1.put("start", "00:00");
        time1.put("end", "23:59");
        times.add(time1);
        body.put("business_time", times);
        body.put("book_ahead_time", "");
        body.put("invoice_support", "2");
        body.put("package_box_price", "1.00");
        body.put("shop_code", "2022");
        try {
            BdPushEntity entity = getBdPushEntity(source, "shop.update", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("querySupplier->:{}", result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 上传菜品
     * 
     * @return
     */
    public boolean createDish(String source) {

        Map<String, Object> body = new HashMap<String, Object>();
        body.put("dish_id", System.currentTimeMillis());
        body.put("baidu_shop_id", "2040164980");
        body.put("name", "滑鸡饭套餐1");
        body.put("price", "1");
        body.put("min_order_num", "1");
        body.put("package_box_num", "1");
        body.put("description", "好吃分量足");
        List<Object> times = new ArrayList<Object>();
        Map<String, String> time1 = new HashMap<String, String>();
        time1.put("start", "08:00");
        time1.put("end", "23:00");
        times.add(time1);
        Map<String, Object> available_times = new HashMap<String, Object>();
        available_times.put("*", times);
        body.put("available_times", available_times);
        body.put("stock", "100");
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        Map<String, String> c = new HashMap<String, String>();
        c.put("name", "优惠");
        c.put("rank", "1");
        list.add(c);
        body.put("category", list);
        body.put("norms", Collections.emptyList());
        body.put("attr", Collections.emptyList());
        try {
            BdPushEntity entity = getBdPushEntity(source, "dish.create", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("querySupplier->:{}", result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 菜品上线
     * 
     * @return
     */
    public boolean onlineDish(String source) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("baidu_shop_id", "2040164980");
        body.put("baidu_dish_id", "2040192003");
        try {
            BdPushEntity entity = getBdPushEntity(source, "dish.online", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("querySupplier->:{}", result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 商户开业
     * 
     * @return
     */
    private boolean openShop(String source, String shopId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("baidu_shop_id", shopId);
        try {
            BdPushEntity entity = getBdPushEntity(source, "shop.open", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("openShop->:{}", result);
            Map<String, Object> map = this.converResult(result);
            if (map.containsKey("errno") && (Integer) map.get("errno") == 0) {
                return true;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("", e);
        }
        return false;
    }

    /**
     * 商户停业
     * 
     * @return
     */
    private boolean closeShop(String source, String shopId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("baidu_shop_id", shopId);
        try {
            BdPushEntity entity = getBdPushEntity(source, "shop.close", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("closeShop->:{}", result);
            Map<String, Object> map = this.converResult(result);
            if (map.containsKey("errno") && (Integer) map.get("errno") == 0) {
                return true;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 店铺状态
     * 
     * 3.0.0
     * 
     * @return
     */
    public boolean shopStatus(String source, String shopId, Integer state) {
        if (state == 1) {
            return this.openShop(source, shopId);
        } else {
            return this.closeShop(source, shopId);
        }
    }

    /**
     * 查看订单
     * 
     * 3.0.0
     * 
     * @return
     */
    public String getOrder(String source, String orderId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("order_id", orderId);
        try {
            BdPushEntity entity = getBdPushEntity(source, "order.get", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("getOrder->:{}", result);
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @SuppressWarnings("rawtypes")
    public TakeOutShopInfo getShop(String source, String shopId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("baidu_shop_id", shopId);
        try {
            BdPushEntity entity = getBdPushEntity(source, "shop.get", body);
            Map<String, String> params = this.converParams(entity);
            String result = httpHelper.doPost(url, params);
            log.info("getShop->:{}", result);
            Map bodyResult = this.converResult(result);
            if (bodyResult.containsKey("errno") && (Integer) bodyResult.get("errno") == 0) {
                Map data = (Map) bodyResult.get("data");
                TakeOutShopInfo shopInfo = new TakeOutShopInfo();
                shopInfo.setePoiId(shopId);
                shopInfo.setName(data.get("name") + "");
                shopInfo.setPictureUrl(data.get("shop_logo") + "");
                shopInfo.setAddress(data.get("address") + "");
                shopInfo.setPhone(data.get("phone") + "");
                shopInfo.setLatitude((Double) data.get("latitude"));
                shopInfo.setLongitude((Double) data.get("longitude"));
                shopInfo.setIsOpen(Integer.parseInt(data.get("status") + ""));
                shopInfo.setPartnerId(data.get("shop_id") + "");
                return shopInfo;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("getShop->{}", e);
        }
        return null;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private Map<String, Object> converResult(String result) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("errno", -1);
        resultMap.put("error", "fail");
        if (StringUtils.isNoneBlank(result)) {
            Map map = JsonHelper.fromJson(result, Map.class);
            if (map.containsKey("body")) {
                resultMap = (Map) map.get("body");
            }
        }
        return resultMap;
    }

    /**
     * 接单
     * 
     * 3.0.0
     * 
     * @return
     */
    public boolean confirmOrder(final String source, final String orderId) {

        threadPool.submit(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                Map<String, Object> body = new HashMap<String, Object>();
                body.put("order_id", orderId);
                BdPushEntity entity = getBdPushEntity(source, "order.confirm", body);
                Map<String, String> params = converParams(entity);
                try {
                    long time = System.currentTimeMillis();
                    String result = httpHelper.doPost(url, params);
                    long t = System.currentTimeMillis() - time;
                    log.info("bd->confirmOrder cost:{}-{}", t, result);
                    Map bodyResult = converResult(result);
                    // if (bodyResult.containsKey("errno") && (Integer) bodyResult.get("errno") == 0) {
                    // return true;
                    // }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    log.error("confirmOrder->error:{}", e);
                }
            }
        });
        return true;
    }

    /**
     * 取消接单
     * 
     * 3.0.0
     * 
     * @return
     */
    public boolean cancelOrder(String source, String orderId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("order_id", orderId);
        body.put("type", -1);
        body.put("reason", "商户取消订单");
        BdPushEntity entity = getBdPushEntity(source, "order.cancel", body);
        Map<String, String> params = this.converParams(entity);
        try {
            String result = httpHelper.doPost(url, params);
            log.info("cancelOrder->:{}", result);
            Map bodyResult = this.converResult(result);
            if (bodyResult.containsKey("errno") && (Integer) bodyResult.get("errno") == 0) {
                return true;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("cancelOrder->error:{}", e);
        }
        return false;
    }

    /**
     * 退款接单
     * 
     * 3.0.0
     * 
     * @return
     */
    public boolean refundOrder(String source, String orderId) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("order_id", orderId);
        BdPushEntity entity = getBdPushEntity(source, "order.partrefund", body);
        Map<String, String> params = this.converParams(entity);
        try {
            String result = httpHelper.doPost(url, params);
            log.info("refundOrder->:{}", result);
            Map bodyResult = this.converResult(result);
            if (bodyResult.containsKey("errno") && (Integer) bodyResult.get("errno") == 0) {
                return true;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("refundOrder->error:{}", e);
        }
        return false;
    }

    /**
     * 订单状态推送
     * 
     * 3.0.0
     * 
     * @return
     */
    public BdPushEntity statusPush(String source, String orderId, String status, String type, String reason) {
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("order_id", orderId);
        body.put("status", status);
        if (StringUtils.isNoneBlank(type)) {
            body.put("type", type);
            body.put("reason", reason);
        }
        BdPushEntity entity = getBdPushEntity(source, "order.status.push", body);
        this.converParams(entity);
        return entity;
    }

    // public String getAuthUrl(Integer auserId, String ePoiId)
    // throws UnsupportedEncodingException {
    // StringBuffer sb = new StringBuffer();
    // sb.append(url);
    // sb.append("?");
    // sb.append("developerId=" + developerId);
    // sb.append("&");
    // sb.append("businessId=" + businessId);
    // sb.append("&");
    // sb.append("ePoiId=" + ePoiId);
    // sb.append("&");
    // sb.append("signKey=" + signKey);
    // sb.append("&");
    // String tmp = callbackUrl + "?auserId=" + auserId;
    // sb.append("callbackUrl=" + URLEncoder.encode(tmp, "utf-8"));
    // return sb.toString();
    // }

    public static void main(String args[]) {
        BaiduService bd = new BaiduService();
        // bd.cancelOrder("64773", "15000012907918");

        // bd.updateShop("64493", "2074313074");

        // System.out.println("\u5355\u5546\u6237\u63a5\u5165\u4e0d\u80fd\u8c03\u7528\u6b64\u63a5\u53e3");

        // bd.updateShop("64341", "2117023992");
        bd.cancelOrder("64341", "15065027251554");
    }
}
